<!--
*@Author: QWP
*@Description: 上传图片
*@Date: 2024-07-10 09:06:11
-->
<template>
  <a-image-preview-group>
    <a-upload
      v-model:file-list="fileList"
      v-bind="$attrs"
      action="#"
      list-type="picture-card"
      multiple
      class="u-upload-img-c"
      :customRequest="customRequest"
      @remove="removeImg"
      @preview="handlePreview"
    >
      <template #itemRender="{ file, actions }">
        <div class="f-flex-column u-item-img">
          <a-image :src="getFileImgUrl(file)" :preview="true" maxWidth="100%" maxHeight="100%">
            <template #previewMask>
              <a-space size="middle">
                <EyeOutlined class="f-cursor u-tool-icon"/>
                <DeleteOutlined class="f-cursor u-tool-icon" @click="(event) => removeImg(file, event)"/>
              </a-space>
            </template>
          </a-image>
        </div>
      </template>
      <div v-if="fileList.length < ($attrs['maxCount'] || 30)">
        <plus-outlined />
        <div style="margin-top: 8px">上传</div>
      </div>
    </a-upload>
  </a-image-preview-group>

</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted, useAttrs, watch, nextTick } from 'vue' 
import { useRoute, useRouter } from 'vue-router'
import { UploadProps } from 'ant-design-vue';
import { PlusOutlined } from '@ant-design/icons-vue';
import { nullC } from '@/util/common';
import { formatImgUrl } from '@/util/format';
import { cloneDeep } from 'lodash'
import { imgApi } from '@/http/api'
import * as fileApi from '@/service/file'
defineOptions({
  name: 'u-upload-img'
})

const props = withDefaults(
  defineProps<{
    value: any,
    fileParams: object,
  }>(),
  {
    value: []
  }
)

// const fileList = reactive<any[]>([])
let fileList = ref<UploadProps['fileList']>([])
const attrs = useAttrs()
const emits = defineEmits(['update:value', 'update:modelValue', 'success'])

watch(() => props, (nval, oval) => {
  fileList.value = nval.value || []
}, { deep: true })

const getBase64 = (file: File) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

const handleCancel = () => {
  previewVisible.value = false;
  previewTitle.value = '';
};

const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
const imgRef = ref();
const handlePreview = async (file: UploadProps['fileList'][number]) => {
  if (!file.url && !file.preview) {
    file.preview = (await getBase64(file.originFileObj)) as string;
  }
  previewImage.value = getFileImgUrl(file);
  previewVisible.value = true;
  previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
  // imgRef.value.click()
};

// 自定义上传
const customRequest = ({ onSuccess, onError, file, onProgress }) => {

  let form = new FormData();
  form.append('storagetype', 'LOCAL')
  form.append('file', file)
  form.append('bucket', nullC(props.fileParams['bucket']))
  form.append('biztype', nullC(props.fileParams['biztype']))

  fileApi.upload(form, {
    onUploadProgress: ({ total, loaded }) => {
      onProgress({ percent: Math.round((loaded / total) * 100) });
    },
  })
  .then(res => {
    if(res.data.code == 0) {
      const data = cloneDeep(res.data.data || {})
      onSuccess({ 
        ...file, 
        ...data,
        filename: nullC(data['originalfilename']) 
      })

      let index = fileList.value.findIndex(i => i.uid == file.uid);
      if(index != -1) {
        let tValue = cloneDeep(fileList.value)
        tValue[index] = {
          ...tValue[index], 
          ...data,
          orderno: index,
          filename: data.originalfilename,
          filetype: data.filetype['code'],
          filetype1: data.filetype['desc'],
          appendix: Object.assign(data, props.fileParams),
        }
        // fileList.splice(0, fileList.length, ...tValue)
        fileList.value = tValue
        emits('update:value', tValue)
        emits('success', tValue)
      }
    }
  })
  .catch(err => {
    onError(err)
  })
}

// 移除
const removeImg = (file, event) => {
  if(event) {
    event.stopPropagation()
  }
  fileList.value = cloneDeep(fileList.value).filter(i => {
    if(i['uid']) {
      return i['uid'] != file.uid
    }
    else if(i['keyid']) {
      return i['keyid'] != file.keyid
    }
  })

  emits('update:value', fileList.value)
}

const getFileImgUrl = (file) => {
  if(file['filepath']) {
    return formatImgUrl(file['filepath'] || '')
  }
  else if(file['thumbUrl']) {
    return file['thumbUrl']
  }
  else if(file['url']) {
    return file['url']
  }
  return ''
}
</script>

<style lang='scss'>
.u-upload-img-c {
  .ant-upload-list-item-container {
    width: 120px !important;
    height: 120px !important;
  }
  .ant-upload-select {
    @extend .ant-upload-list-item-container
  }
  .u-item-img {
    position: relative;
    width: 100%; 
    height: 100%;
    justify-content: center; 
    border: 1px solid #ccc; 
    border-radius: 6px;
    &:hover {
      .u-item-tool {
        display: flex;
        flex-direction: column
      }
    }
    .ant-image {
      max-width: 100%;
      max-Height: 100%;
      .ant-image-img {
        @extend .ant-image 
      }
    }
    .u-item-tool {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      justify-content: center;
      align-items: center;
      background-color: rgba(0, 0, 0, 0.4);
    }
    .u-tool-icon {
      color: #ccc;
      font-size: 18px;
    }
  }
}
</style>